﻿using DimensionsHelper.LanguageService.Protocol;

namespace DimensionsHelper.LanguageService.Syntax;

public class Block : Statement
{
    private SyntaxList<LabelDeclaration>? _labels;
    private SyntaxList<Statement>? _statements;
    private List<FunctionDeclaration>? _functions;

    internal Block(SyntaxNode? parent) : base(SyntaxKinds.Block, parent)
    {
    }

    /// <summary>
    ///     默认的空语句块，可用于初始化。
    /// </summary>
    public static Block Default { get; } = new(null);


    /// <summary>
    ///     获取已定义的语句块行标签
    /// </summary>
    public IReadOnlyList<LabelDeclaration> Labels => _labels == null ? new List<LabelDeclaration>() : _labels;
    
    /// <summary>
    ///     获取语法列表中的函数声明节点
    /// </summary>
    public IReadOnlyList<FunctionDeclaration> Functions => _functions ?? [];

    /// <summary>
    ///     子语句列表，此列表不等同于 Children 列表。
    /// </summary>
    public IReadOnlyList<Statement> Statements =>
        _statements == null ? new List<Statement>() : _statements;


    public override int Start => _statements?.Start ?? 0;


    public override int End => _statements?.End ?? 0;


    public override int Width => _statements?.Width ?? 0;


    public static bool IsEmptyOrDefault(Block? block)
    {
        return block == null || ReferenceEquals(block, Default) || block.IsEmpty;
    }


    internal override void SetUri(DocumentUri uri)
    {
        base.SetUri(uri);
        _labels?.SetUri(uri);
        _statements?.SetUri(uri);
    }


    internal void AddFunctions(IEnumerable<FunctionDeclaration> functions)
    {
        (_functions ??= []).AddRange(functions);
    }


    /// <summary>
    ///     添加一个行标签
    /// </summary>
    public void AddLabel(LabelDeclaration label)
    {
        AddChildMember(ref _labels, label);
    }


    public SyntaxNode? GetLabel(string labelName)
    {
        return _labels?.Find(l => labelName.Equals(l.Text, StringComparison.OrdinalIgnoreCase));
    }


    /// <summary>
    ///     添加一个新的子语句
    /// </summary>
    public void AddStatement(Statement statement)
    {
        AddChildMember(ref _statements, statement);
        // 如果是函数声明，添加到列表
        if (statement.Is<FunctionDeclaration>(SyntaxKinds.FunctionDeclaration, out var functionDeclaration))
        {
            (_functions ??= []).Add(functionDeclaration);
        }
        // 如果是语法树引用，导入函数声明
        else if (statement.Is<SyntaxTreeIncludeNode>(SyntaxKinds.SyntaxTreeInclude, out var treeIncludeNode) &&
                 treeIncludeNode.GetSyntaxTree() is { } tree)
        {
            (_functions ??= []).AddRange(tree.GetLocalFunctions());
        }
    }


    public Statement? FindStatement(Predicate<Statement> predicate)
    {
        return _statements?.Find(predicate);
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        AcceptList(visitor, _labels);
        AcceptList(visitor, _statements);
    }
}


public static partial class NodeFactory
{
    public static Block CreateBlock(SyntaxNode? parent)
    {
        return new Block(parent);
    }
}